
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include </home/marceng/Desktop/read.c>
#include </home/marceng/Desktop/write.c>
#include </home/marceng/Desktop/driver.c>
#include </home/marceng/Desktop/file.h>

int main( int argc, char *argv[] )
{
int Status,Status1, mem_pcb;
int descritor, tamanho,posicao;
char *buffer;
PCB *pcb_ptr;
buffer_arq buffer_SO;
buffer_usuario buffer_arquivo;
i_node inode;
laa lista_arquivos_abertos;

//bloco bloco_teste;
buffer_arq bloco_teste;

//criando as variaveis chave e o id da fila
key_t chave = ID_MSG_REQUISICAO_DRIVER;
int id_msg_requisicao;
key_t chave1 = ID_MSG_RESPOSTA;
int id_msg_resposta;

cache_blocos *cache;
mem_comp_inout *cache_inout;

int pid;

//criando as variaveis chave dos semaforos
int id_semaforo_inode;
int id_semaforo_cache;

	//Associa a mem�ria compartilhada do PCB
	mem_pcb = shmget( MEM_PCB, sizeof(PCB), 0);
	pcb_ptr = (PCB*) shmat(mem_pcb, NULL, 0);	

	descritor =0;
	tamanho = 50;
	posicao=200;
	int i=0;
	for( i;i<1024;i++)
	  buffer_SO.buffer_arq[i]="a";
	
	int j=1;
	
	for(j; j<10; j++)
	{
	pcb_ptr->tabela_descritores[i].ponteiro_arq = 10;
	pcb_ptr->tabela_descritores[i].laa_ptr = NULL;
	pcb_ptr->tabela_descritores[i].buffer_arquivo= &buffer_SO;
	}
	
	pcb_ptr->tabela_descritores[0].ponteiro_arq = 5;
	pcb_ptr->tabela_descritores[0].laa_ptr =&lista_arquivos_abertos;
	strcpy(pcb_ptr->tabela_descritores[0].buffer_arquivo, &buffer_SO);
	pcb_ptr->tabela_descritores[0].modo_abertura = 1;
	pcb_ptr->tabela_descritores[0].aberto = 1;
	
	
	//criando fila de mesagens
	if( (id_msg_requisicao = msgget(chave, IPC_CREAT | 0666)) == -1 )
	{
		fprintf(stderr,"Impossivel criar a fila de mensagens!\n");
		exit(1);
	}

	if( (id_msg_resposta = msgget(chave1, IPC_CREAT | 0666)) == -1 )
	{
		fprintf(stderr,"Impossivel criar a fila de mensagens!\n");
		exit(1);
	}
	
/*************************************************************************************************************/
// Memorias compartilhadas
	/*
	 * Criando a memoria compartilhada PCB
	 */
	mem_pcb_id = shmget( MEM_PCB, sizeof(PCB), IPC_CREAT | 0666);
	mem_pcb_addr = shmat(mem_pcb_id, NULL, 0);

	#ifdef MSG_EST
	printf("Criando memoria compartilhada PCB...\n");
	#endif	

	/*
	 * Criando o primeiro noh da memoria compartilhada LAA
	 */
	mem_taa_id = shmget( MEM_LAA, sizeof(laa), IPC_CREAT | 0666);
	mem_taa_addr = shmat(mem_taa_id, NULL, 0);

	laa *taa;
	taa = (laa *) mem_taa_addr;
	// inicializa LAA

	// coloca NULL como chave do proximo
	taa->prox = NULL;
	
	#ifdef MSG_EST
	printf("Criando memoria compartilhada LAA...\n");
	#endif	

	/*
	 * Criando a memoria compartilhada SuperBloco
	 */
	mem_superbloco_id = shmget( MEM_SUPERBLOCO, sizeof(Superbloco), IPC_CREAT | 0666);
	mem_superbloco_addr = shmat(mem_superbloco_id, NULL, 0);
	
	#ifdef MSG_EST
	printf("Criando memoria compartilhada SuperBloco...\n");
	#endif	
	
	//Criacao da memoria compartilhada pra usar como cache
	if( (shm_cache_blocos = shmget(SHM_CACHE_KEY, sizeof(cache_blocos), IPC_CREAT | 0666)) == -1 ) 
	{
		printf("Impossivel criar a memoria compartilhada(Cache Blocos)!\n");
	}
/*	
	 
/*************************************************************************************************************/
// Semaforos
	
	/*
	 * Criando o semaforo para proteger a LAA
	 */	
	id_semaforo_laa = semget( SEM_LAA, 1, IPC_CREAT | 0666 );

	#ifdef MSG_EST
	printf("Criando semaforo para proteger a TAA...\n");
	#endif	

	/*
	 * Criando o semaforo para proteger o Superbloco
	 */	
	id_semaforo_super = semget( SEM_SUPER_KEY, 1, IPC_CREAT | 0666 );
	
	#ifdef MSG_EST
	printf("Criando semaforo para proteger o SuperBloco...\n");
	#endif	



	key_taa = MEM_LAA;
	

	
	
	int count;
	int rtn = 1;
	for( count = 0; count < 1; count++ ) {
		if( rtn != 0 ) {
			pid = rtn = fork();
		} else {
			break;
		}
	}

	//um processo sera o driver!!
	if(rtn == 0){
		printf("\ndriver acionado\n");
		driver();
	}
	else{
		Status = readd(descritor, &buffer_arquivo, 30, 10);
		Status1 = ffwrite(descritor, &buffer_arquivo, tamanho,posicao);
	}
	
	printf("\nStatus Read: %i\n", Status);
	printf("\nStatus Write: %i\n", Status1);
	//removendo fila de mensagens
	if(msgctl(id_msg_requisicao,IPC_RMID,NULL) != 0 )
	{
		fprintf(stderr,"Impossivel remover a fila de mensagem!\n");
		exit(1);
	}

	if(msgctl(id_msg_resposta,IPC_RMID,NULL) != 0 )
	{
		fprintf(stderr,"Impossivel remover a fila de mensagem!\n");
		exit(1);
	}
	/* 
	* Remove a memoria compartilhda do PCB
        */
   	shmctl(mem_pcb_id ,IPC_RMID,NULL);

	/* 
	* Remove a memoria compartilhda do Superbloco
        */
   	shmctl(mem_superbloco_id ,IPC_RMID,NULL);

	/* 
	* Remove a memoria compartilhda da Tabela de Arquivos Abertos
        */
   	shmctl(mem_taa_id ,IPC_RMID,NULL);

	/*
        * Removendo o semaforo do Superbloco
        */
        semctl( id_semaforo_super, 0, IPC_RMID, 0);

	/*
        * Removendo o semaforo da Lista de Arquivos Abertos
        */
        semctl( id_semaforo_laa, 0, IPC_RMID, 0);

	/* 
	* Remove a memoria compartilhda do Buffer SO
        */
   	//shmctl(mem_buffer_id ,IPC_RMID,NULL); 


	return 0;
}